<template>
  <div class="antv-test">
    <el-button @click="()=>{ 
      this.$router.push('/wflow-form-test')
    }">跳转wflow</el-button>
    <a href="https://x6.antv.antgroup.com/" target="_blank">
      <h1 class="title"><i class="title-image"></i>AntV</h1>
    </a>
    <!-- graph画布 -->
    <div id="container" @dragover="dragoverDiv"></div>
    <!-- 右侧图像 -->
    <div class="menu-list">
      <div
        v-for="item in moduleList"
        :key="item.id"
        draggable="true"
        @dragend="handleDragEnd($event, item)"
      >
        <p>{{ item.name }}</p>
      </div>
      <!-- 按钮 -->
      <div @click="addNode">添加节点</div>
      <div @click="saveNode">保存节点信息</div>
    </div>
  </div>
</template>

<script>
import { Graph } from "@antv/x6";
import { Dnd } from "@antv/x6-plugin-dnd";
export default {
  title:"antV案例",
  data() {
    return {
      // 列表可拖动模块
      moduleList: [
        {
          id: 1,
          name: "开始模块",
          type: "initial", // 初始模块(用于区分样式)
        },
        {
          id: 2,
          name: "结束模块",
          type: "initial",
        },
        {
          id: 3,
          name: "逻辑模块1",
          type: "logic", // 逻辑模块(用于区分样式)
        },
        {
          id: 4,
          name: "逻辑模块2",
          type: "logic",
        },
      ],
      graph: null, // 画布实例对象
      dnd: null, // 拖拽实例
    };
  },
  mounted() {
    this.initGraph();
  },
  methods: {
    // 添加节点
    addHandleNode(x, y, id, name) {
      this.graph.addNode({
        id: id,
        shape: "rect",
        position: {
          x: x,
          y: y,
        },
        size: {
          width: 100,
          height: 40,
        },
        zIndex: 12,
        label: name,
        // tools:['node-editor']
      });
    },

    // 拖动后松开鼠标触发事件
    handleDragEnd(e, item) {
      console.log(e);
      this.addHandleNode(
        e.pageX - 240,
        e.pageY - 40,
        new Date().getTime(),
        item.name,
        item.type
      );
    },

    // 拖动节点到画布中鼠标样式变为可拖动状态
    dragoverDiv(ev) {
      // console.log('进入',ev)
      ev.preventDefault();
    },
    // 初始化流程图画布
    initGraph() {
      let container = document.getElementById("container");
      this.graph = new Graph({
        container: container, // 画布容器
        width: container.offsetWidth, // 画布宽
        height: container.offsetHeight, // 画布高
        background: false, // 背景（透明）
        snapline: true, // 对齐线
        register: true, // 是否监听容器大小改变，并自动更新画布大小。
        highlighting: {
          // 高亮选项
        },
        interacting: {
          // 定制节点和边的交互行为。
        },
        // 配置连线规则
        connecting: {
          snap: true, // 自动吸附
          allowBlank: false, //是否允许连接到画布空白位置的点
          allowMulti: true, //是否允许在相同的起始节点和终止之间创建多条边
          allowLoop: false, //是否允许创建循环连线，即边的起始节点和终止节点为同一节点
          highlight: true, //拖动边时，是否高亮显示所有可用的节点
          // eslint-disable-next-line
          validateEdge({ edge, type, previous }) {
            // // 设置连线样式
            // edge.setAttrs({
            //   line: {
            //     stroke: "#275da3",
            //     strokeWidth: 4,
            //   },
            // });
            return true;
          },
        },
        panning: {
          enabled: true,
        },
        mousewheel: {
          enabled: true, // 支持滚动放大缩小
        },
        grid: {
          type: "mesh",
          size: 20, // 网格大小 10px
          visible: true, // 渲染网格背景
          args: {
            color: "#eeeeee", // 网格线/点颜色
            thickness: 2, // 网格线宽度/网格点大小
          },
        },
      });

      this.dnd = new Dnd({
        target: this.graph,
      });

      this.nodeAddEvent();
    },
    // 绑定事件
    nodeAddEvent() {
      // 节点绑定悬浮事件
      this.graph.on("node:click", ({ node }) => {
        console.log("node", node);
        // 判断是否有选中过节点
        if (this.curSelectNode) {
          // 移除选中状态
          this.curSelectNode.removeTools();
          // 判断两次选中节点是否相同
          if (this.curSelectNode !== node) {
            this.curSelectNode = null;
            // 注销连线事件
            node.setAttrs({
              body: {
                magnet: false,
              },
            });
            node.addTools([
              {
                // 显示边界线
                name: "boundary",
                args: {
                  attrs: {
                    fill: "#16B8AA",
                    stroke: "#2F80EB",
                    strokeWidth: 1,
                    fillOpacity: 0.1,
                  },
                },
              },
              {
                // 显示节点删除按钮
                name: "button-remove",
                args: {
                  x: "100%",
                  y: 0,
                  offset: {
                    x: 0,
                    y: 0,
                  },
                },
              },
            ]);
            this.curSelectNode = node;
            // 添加连线事件
            node.setAttrs({
              body: {
                magnet: true,
              },
            });
          } else {
            this.curSelectNode = null;
            // 注销连线事件
            node.setAttrs({
              body: {
                magnet: false,
              },
            });
          }
        } else {
          this.curSelectNode = node;
          node.addTools([
            {
              name: "boundary",
              args: {
                attrs: {
                  fill: "#16B8AA",
                  stroke: "#2F80EB",
                  strokeWidth: 1,
                  fillOpacity: 0.1,
                },
              },
            },
            {
              name: "button-remove",
              args: {
                x: "100%",
                y: 0,
                offset: {
                  x: 0,
                  y: 0,
                },
              },
            },
          ]);
          // 添加连线事件
          node.setAttrs({
            body: {
              magnet: true,
            },
          });
        }
      });

      // 连线绑定悬浮事件
      this.graph.on("cell:mouseenter", ({ cell }) => {
        if (cell.shape == "edge") {
          cell.addTools([
            "button-remove",
            "source-arrowhead",
            "target-arrowhead",
          ]);
          cell.zIndex = 99;
        }
      });

      this.graph.on("cell:mouseleave", ({ cell }) => {
        if (cell.shape === "edge") {
          cell.removeTools();
          cell.zIndex = 1;
        }
      });
    },

    // 添加数据
    addNode() {
      this.graph.fromJSON([
        {
          id: "az",
          shape: "rect",
          position: {
            x: 240,
            y: 240,
          },
          size: {
            width: 100,
            height: 40,
          },
          zIndex: 12,
          label: "王五",
          // tools:['node-editor']
        },
        {
          id: "node1",
          x: 140,
          y: 40,
          width: 100,
          height: 40,
          label: "张三",
          shape: "rect",
        },
        {
          id: "node2",
          x: 40,
          y: 240,
          width: 100,
          height: 40,
          label: "李四",
          shape: "ellipse",
        },
        {
          id: "edge1",
          source: "node1",
          target: "node2",
          shape: "edge",
        },
        {
          id: "edge4",
          source: "node1",
          target: "az",
          shape: "edge",
        },
      ]);
    },

    // 保存数据
    saveNode() {
      console.log(this.graph.toJSON());
    },
  },
};
</script>

<style scoped>
.antv-test > div {
  display: inline-block;
  float: left;
  margin: 12px 24px;
}

.title {
  text-align: center;
}

.title-image {
  display: inline-block;
  width: 32px;
  height: 32px;
  background: url("https://gw.alipayobjects.com/zos/antfincdn/FLrTNDvlna/antv.png");
  background-size: 32px 32px;
}

#container {
  width: 500px;
  height: 500px;
  border: 1px solid;
}
</style>
